﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.IO;

namespace SCGILite.Helper
{
    public static class HtmlHelper
    {
        #region HtmlEncode
        static int IndexOfHtmlEncodingChars(string s, int startPos)
        {
            for (int i = startPos; i < s.Length; i++)
            {
                char ch = s[i];
                if (ch <= '>')
                {
                    switch (ch)
                    {
                        case '&':
                        case '\'':
                        case '"':
                        case '<':
                        case '>':
                            return i;
                    }
                }
                else if ((ch >= '\x00a0') && (ch < 'Ā'))
                {
                    return i;
                }
            }
            return -1;
        }

        static void HtmlEncode(char ch, Action<char> wChar, Action<string> wString)
        {
            if (ch <= '>')
            {
                switch (ch)
                {
                    case '&':
                        {
                            wString("&amp;");
                            return;
                        }
                    case '\'':
                        {
                            wString("&#39;");
                            return;
                        }
                    case '"':
                        {
                            wString("&quot;");
                            return;
                        }
                    case '<':
                        {
                            wString("&lt;");
                            return;
                        }
                    case '>':
                        {
                            wString("&gt;");
                            return;
                        }
                }
                wChar(ch);
            }
            else if ((ch >= '\x00a0') && (ch < 'Ā'))
            {
                wString("&#");
                wString(ch.ToString(NumberFormatInfo.InvariantInfo));
                wChar(';');
            }
            else
            {
                wChar(ch);
            }
        }

        static void HtmlEncode(string value, Action<char> wChar, Action<string> wString)
        {
            if (value != null)
            {
                int num = IndexOfHtmlEncodingChars(value, 0);
                if (num == -1)
                {
                    wString(value);
                }
                else
                {
                    for (int i = 0; i < num; i++)
                    {
                        wChar(value[i]);
                    }
                    for (int i = num; i < value.Length; i++)
                    {
                        HtmlEncode(value[i], wChar, wString);
                    }
                }
            }
        }

        public static void HtmlEncode(string value, TextWriter output)
        {
            if (value != null)
            {
                if (output == null)
                {
                    throw new ArgumentNullException("output");
                }
                HtmlEncode(value, output.Write, output.Write);
            }
        }

        public static void HtmlEncode(string value, Stream output, Encoding encoding)
        {
            TextWriter w = new StreamWriter(output, encoding);
            HtmlEncode(value, w);
        }
        public static void HtmlEncode(string value, StringBuilder b)
        {
            Action<char> wChar = (c) => { b.Append(c); };
            Action<string> wString = (c) => { b.Append(c); };
            HtmlEncode(value, wChar, wString);
        }
        public static string HtmlEncode(string value)
        {
            StringBuilder b = new StringBuilder();
            HtmlEncode(value, b);
            return b.ToString();
        }
        #endregion
    }
}
